function reduce ( ... JSarguments : any []) : any {
    let values : any = JSarguments [0];
    let reducer : any = JSarguments [1];
    let value : any = JSarguments [2];
    if (typeof reducer !== "function") throw new TypeError ("reducer is not a function");
    const iterator : any = values [Symbol.iterator] ();
    let done ! : any;
    let next ! : any;
    let index : number = - 1;
    if (JSarguments.length < 3) {
        ({
            done,
            value
        } = iterator.next ());
        if (done) return;
        ++ index;
    }
    while ({
        done,
        value : next
    } = iterator.next (), ! done) {
        value = reducer (value, next, ++ index, values);
    }
    return value;
}
